package com.hx.zhg.web.config;

import com.dangdang.ddframe.job.api.ElasticJob;
import com.dangdang.ddframe.job.config.JobCoreConfiguration;
import com.dangdang.ddframe.job.config.simple.SimpleJobConfiguration;
import com.dangdang.ddframe.job.lite.config.LiteJobConfiguration;
import com.dangdang.ddframe.job.lite.spring.api.SpringJobScheduler;
import com.dangdang.ddframe.job.reg.zookeeper.ZookeeperRegistryCenter;
import com.hx.zhg.service.annotation.Task;
import com.hx.zhg.service.utils.SpringUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.Optional;

@Component
public class RegisterJobCenter implements InitializingBean {

    private static final Logger log = LoggerFactory.getLogger(RegisterJobCenter.class);

    @Autowired
    private ZookeeperRegistryCenter regCenter;

    @Autowired
    private SpringUtil springUtil;

    @Override
    public void afterPropertiesSet() throws Exception {
        // 获取 注解 Task 的Bean
        Map<String, Object> registerJobs = springUtil.applicationContext.getBeansWithAnnotation(Task.class);
        // 开始遍历
        for (Map.Entry<String, Object> entry : registerJobs.entrySet()) {
            try {
                Object object = entry.getValue();
                if (!(object instanceof ElasticJob)) {
                    throw new ClassCastException("[" + object.getClass().getName() + "] The class type is not com.dangdang.ddframe.job.api.ElasticJob");
                }
                Task task = AnnotationUtils.findAnnotation(object.getClass(), Task.class);
                SpringJobScheduler springJobScheduler = new SpringJobScheduler((ElasticJob) object, regCenter, getJobConfiguration(task, object));
                springJobScheduler.init();
                log.info("JobName: {} Register Successfully .", task.jobName());
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
        }
    }

    /**
     * description: 构建 Job 配置
     *
     * @param taskJob
     * @param object
     * @return
     */
    private LiteJobConfiguration getJobConfiguration(Task taskJob, Object object) {
        // 参数校验
        Optional.ofNullable(taskJob.jobName()).orElseThrow(() -> new IllegalArgumentException("The jobName cannot be null !"));
        Optional.ofNullable(taskJob.cron()).orElseThrow(() -> new IllegalArgumentException("The cron cannot be null !"));
        Optional.ofNullable(taskJob.desc()).orElseThrow(() -> new IllegalArgumentException("The desc cannot be null !"));
        // 构建配置
        SimpleJobConfiguration simpleJobConfiguration = new SimpleJobConfiguration(
                JobCoreConfiguration.newBuilder(taskJob.jobName(), taskJob.cron(), taskJob.shardingTotalCount())
                        .shardingItemParameters(StringUtils.isEmpty(taskJob.shardingItemParameters()) ? null : taskJob.shardingItemParameters())
                        .description(taskJob.desc())
                        .failover(taskJob.failover())
                        .jobParameter(StringUtils.isEmpty(taskJob.jobParameter()) ? null : taskJob.jobParameter()).build(), object.getClass().getName());
        return LiteJobConfiguration.newBuilder(simpleJobConfiguration).overwrite(taskJob.overwrite()).monitorExecution(true).build();
    }
}
